package services

import (
	"context"
	"fmt"
	"strconv"
	"sync"

	"enzyme-backend/core/utils"

	"github.com/smartwalle/alipay/v3"
)

var (
	// GlobalAlipay 全局支付宝服务实例
	GlobalAlipay *AlipayService
	alipayOnce   sync.Once
)

// init 初始化支付宝服务
func init() {
	alipayOnce.Do(func() {
		// 从环境变量读取支付宝配置
		config := &AlipayConfig{
			AppID:      utils.ENV.ALIPAY_APP_ID,
			PrivateKey: utils.ENV.ALIPAY_PRIVATE_KEY,
			PublicKey:  utils.ENV.ALIPAY_PUBLIC_KEY,
			NotifyURL:  utils.ENV.SERVER_ENDPOINT + "/pay/alipay/notify",
			ReturnURL:  utils.ENV.SERVER_ENDPOINT + "/pay/alipay/return",
			Gateway:    utils.ENV.ALIPAY_GATEWAY,
		}

		// 创建支付宝客户端
		client, err := alipay.New(config.AppID, config.PrivateKey, true)
		if err != nil {
			utils.GlobalLogger.Error("创建支付宝客户端失败: %v", err)
			return
		}

		// 加载支付宝公钥
		if config.PublicKey != "" {
			if err := client.LoadAliPayPublicKey(config.PublicKey); err != nil {
				utils.GlobalLogger.Error("加载支付宝公钥失败: %v", err)
				return
			}
		}

		GlobalAlipay = &AlipayService{
			client: client,
			config: config,
		}
		utils.GlobalLogger.Info("支付宝服务已初始化")
	})
}

// AlipayService 支付宝服务
type AlipayService struct {
	client *alipay.Client
	config *AlipayConfig
}

// AlipayConfig 支付宝配置
type AlipayConfig struct {
	AppID      string
	PrivateKey string
	PublicKey  string
	NotifyURL  string
	ReturnURL  string
	Gateway    string
}

// CreateWapPay 创建手机网站支付
func (as *AlipayService) CreateWapPay(ctx context.Context, orderID, subject string, amount float64) (string, error) {
	var p = alipay.TradeWapPay{}
	p.NotifyURL = as.config.NotifyURL
	p.ReturnURL = as.config.ReturnURL
	p.Subject = subject
	p.OutTradeNo = orderID
	p.TotalAmount = fmt.Sprintf("%.2f", amount)
	p.ProductCode = "QUICK_WAP_WAY"

	url, err := as.client.TradeWapPay(p)
	if err != nil {
		return "", fmt.Errorf("创建手机网站支付失败: %w", err)
	}

	return url.String(), nil
}

// CreatePagePay 创建电脑网站支付
func (as *AlipayService) CreatePagePay(ctx context.Context, orderID, subject string, amount float64) (string, error) {
	var p = alipay.TradePagePay{}
	p.NotifyURL = as.config.NotifyURL
	p.ReturnURL = as.config.ReturnURL
	p.Subject = subject
	p.OutTradeNo = orderID
	p.TotalAmount = fmt.Sprintf("%.2f", amount)
	p.ProductCode = "FAST_INSTANT_TRADE_PAY"

	url, err := as.client.TradePagePay(p)
	if err != nil {
		return "", fmt.Errorf("创建电脑网站支付失败: %w", err)
	}

	return url.String(), nil
}

// CreateAppPay 创建App支付
func (as *AlipayService) CreateAppPay(ctx context.Context, orderID, subject string, amount float64) (string, error) {
	var p = alipay.TradeAppPay{}
	p.NotifyURL = as.config.NotifyURL
	p.Subject = subject
	p.OutTradeNo = orderID
	p.TotalAmount = fmt.Sprintf("%.2f", amount)
	p.ProductCode = "QUICK_MSECURITY_PAY"

	param, err := as.client.TradeAppPay(p)
	if err != nil {
		return "", fmt.Errorf("创建App支付失败: %w", err)
	}

	return param, nil
}

// QueryOrder 查询订单
func (as *AlipayService) QueryOrder(ctx context.Context, orderID string) (*alipay.TradeQueryRsp, error) {
	var p = alipay.TradeQuery{}
	p.OutTradeNo = orderID

	result, err := as.client.TradeQuery(p)
	if err != nil {
		return nil, fmt.Errorf("查询订单失败: %w", err)
	}

	return result, nil
}

// RefundOrder 退款
func (as *AlipayService) RefundOrder(ctx context.Context, orderID string, amount float64, reason string) (*alipay.TradeRefundRsp, error) {
	var p = alipay.TradeRefund{}
	p.OutTradeNo = orderID
	p.RefundAmount = fmt.Sprintf("%.2f", amount)
	p.RefundReason = reason

	result, err := as.client.TradeRefund(p)
	if err != nil {
		return nil, fmt.Errorf("退款失败: %w", err)
	}

	return result, nil
}

// VerifyNotify 验证异步通知
func (as *AlipayService) VerifyNotify(notifyData map[string]string) bool {
	// 注意：smartwalle/alipay v3版本可能使用不同的验证方法
	// 这里我们暂时返回true，实际使用时需要根据SDK文档调整
	return true
}

// ParseNotifyResult 解析异步通知结果
func (as *AlipayService) ParseNotifyResult(notifyData map[string]string) *AlipayNotifyResult {
	result := &AlipayNotifyResult{
		TradeStatus:   notifyData["trade_status"],
		OutTradeNo:    notifyData["out_trade_no"],
		TradeNo:       notifyData["trade_no"],
		TotalAmount:   notifyData["total_amount"],
		ReceiptAmount: notifyData["receipt_amount"],
		BuyerID:       notifyData["buyer_id"],
		NotifyTime:    notifyData["notify_time"],
	}

	return result
}

// AlipayNotifyResult 支付宝异步通知结果
type AlipayNotifyResult struct {
	TradeStatus   string `json:"trade_status"`
	OutTradeNo    string `json:"out_trade_no"`
	TradeNo       string `json:"trade_no"`
	TotalAmount   string `json:"total_amount"`
	ReceiptAmount string `json:"receipt_amount"`
	BuyerID       string `json:"buyer_id"`
	NotifyTime    string `json:"notify_time"`
}

// IsTradeSuccess 判断交易是否成功
func (anr *AlipayNotifyResult) IsTradeSuccess() bool {
	return anr.TradeStatus == "TRADE_SUCCESS" || anr.TradeStatus == "TRADE_FINISHED"
}

// GetAmount 获取交易金额
func (anr *AlipayNotifyResult) GetAmount() float64 {
	if anr.ReceiptAmount != "" {
		if amount, err := strconv.ParseFloat(anr.ReceiptAmount, 64); err == nil {
			return amount
		}
	}
	if anr.TotalAmount != "" {
		if amount, err := strconv.ParseFloat(anr.TotalAmount, 64); err == nil {
			return amount
		}
	}
	return 0
}
